package com.example.demo10_json_login.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定义登录逻辑，实现 json 登录 和验证码校验功能
 */
public class LoginFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }
        String verifyCode = (String) request.getSession().getAttribute("verify_code");
        if (request.getContentType().equalsIgnoreCase("application/json") ||
                request.getContentType().equalsIgnoreCase("application/json;charset=UTF-8")) {
            Map<String, String> loginData;
            try {
                loginData = new ObjectMapper().readValue(request.getInputStream(), Map.class);
            } catch (Exception e) {
                loginData = new HashMap<>();
            }
            String code = loginData.get("code");
            checkCode(code, verifyCode);
            String username = loginData.get(getUsernameParameter());
            String password = loginData.get(getPasswordParameter());
            username = (username == null) ? "" : username;
            password = (password == null) ? "" : password;
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
            setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        } else {
            checkCode(request.getParameter("code"), verifyCode);
            return super.attemptAuthentication(request, response);
        }
    }

    public void checkCode(String code, String verifyCode) {
        if (code == null || !code.equalsIgnoreCase(verifyCode)) {
            throw new AuthenticationServiceException("验证码错误");
        }
    }
}

